import tkinter as tk
from tkinter import ttk, messagebox, simpledialog, scrolledtext
import configparser
import os
from datetime import datetime
import time
import pyautogui
from tkinter import messagebox
import threading
from main_analysis import start_analysis
from main_analysis import setup_logging
from pathlib import Path
from cryptography.fernet import Fernet
from sys import exit
from DeviceManagerClient import DeviceManagerClient
from spiderDataSSC import spiderData
from jssc_four import spiderCharData
from jssc_four_1 import spiderCharData1
from jssc_week import spiderWeekCharData
from app import *
import webbrowser
import subprocess
import os
import sys


CONFIG_FILE = 'config.ini'
RESULT_FILE = 'result.ini'
CONTROL_FILE = 'control.ini'
per_cfg_file = 'per_cfg.ini'
LOG_FILE = './runtime/logs/myapp.log'


def open_with_chrome(file_path):
    """优先使用Google Chrome打开文件"""
    # 常见Chrome安装路径（跨平台）
    chrome_paths = {
        'win32': [
            os.path.expandvars(r"%ProgramFiles%\Google\Chrome\Application\chrome.exe"),
            os.path.expandvars(r"%ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe"),
            os.path.expandvars(r"%LocalAppData%\Google\Chrome\Application\chrome.exe")
        ],
        'darwin': [
            "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
        ],
        'linux': [
            "/usr/bin/google-chrome",
            "/usr/bin/chromium-browser",
            "/usr/bin/chromium"
        ]
    }

    # 尝试所有可能的Chrome路径
    for path in chrome_paths.get(sys.platform, []):
        if os.path.exists(path):
            try:
                # 使用Chrome打开文件
                subprocess.Popen([path, file_path])
                return True
            except Exception:
                continue
    return False

def open_with_browser(file_path):
    """使用主流浏览器打开文件（优先级：Chrome > Edge > Firefox > Safari > 默认浏览器）"""
    # 转换文件路径为file://格式
    file_url = f'file:///{os.path.abspath(file_path).replace(os.sep, "/")}'
    
    # 1. 优先尝试Chrome
    if open_with_chrome(file_url):
        print("使用 Google Chrome 打开")
        return True
    
    # 2. 尝试Microsoft Edge
    try:
        edge_path = None
        if sys.platform == 'win32':
            edge_path = os.path.expandvars(r"%ProgramFiles(x86)%\Microsoft\Edge\Application\msedge.exe")
        elif sys.platform == 'darwin':
            edge_path = "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"
        
        if edge_path and os.path.exists(edge_path):
            subprocess.Popen([edge_path, file_url])
            print("使用 Microsoft Edge 打开")
            return True
    except:
        pass
    
    # 3. 尝试Firefox
    try:
        firefox_path = None
        if sys.platform == 'win32':
            firefox_path = os.path.expandvars(r"%ProgramFiles%\Mozilla Firefox\firefox.exe")
        elif sys.platform == 'darwin':
            firefox_path = "/Applications/Firefox.app/Contents/MacOS/firefox"
        elif sys.platform == 'linux':
            firefox_path = "/usr/bin/firefox"
        
        if firefox_path and os.path.exists(firefox_path):
            subprocess.Popen([firefox_path, file_url])
            print("使用 Mozilla Firefox 打开")
            return True
    except:
        pass
    
    # 4. 尝试Safari (macOS)
    if sys.platform == 'darwin':
        try:
            subprocess.Popen(["/usr/bin/open", "-a", "Safari", file_url])
            print("使用 Safari 打开")
            return True
        except:
            pass
    
    # 5. 回退到默认浏览器
    try:
        webbrowser.open(file_url)
        print("使用系统默认浏览器打开")
        return True
    except:
        return False

class SimpleLoadingDialog:
    def __init__(self, parent, title="加载中", message="请稍候..."):
        # 创建顶层窗口
        self.dialog = tk.Toplevel(parent)
        self.dialog.title(title)
        self.dialog.transient(parent)  # 设置为临时窗口
        self.dialog.grab_set()  # 模态对话框
        self.dialog.resizable(False, False)
        
        # 设置窗口位置居中
        self.dialog.geometry("300x120")
        self.center_window()
        
        # 添加内容
        tk.Label(self.dialog, text=message, font=("Arial", 10)).pack(pady=10)
        
        # 添加进度条
        self.progress = ttk.Progressbar(
            self.dialog, 
            mode='indeterminate',
            length=250
        )
        self.progress.pack(pady=5)
        self.progress.start(10)  # 开始动画
    
    def center_window(self):
        """将窗口居中显示"""
        self.dialog.update_idletasks()
        width = self.dialog.winfo_width()
        height = self.dialog.winfo_height()
        x = (self.dialog.winfo_screenwidth() - width) // 2
        y = (self.dialog.winfo_screenheight() - height) // 2
        self.dialog.geometry(f"+{x}+{y}")
    
    def close(self):
        """关闭加载框"""
        self.progress.stop()
        self.dialog.grab_release()
        self.dialog.destroy()


class ActivationSystem:
    def __init__(self):
        # 生成或加载加密密钥（实际应用中应该安全存储）
        self.key = b'SDBsdp8GCgmvbCBbrxbEr39t9cfD0FofX3T2XaErjD0='  # 必须32字节
        self.cipher = Fernet(self.key)

    def generate_memorable_code(self):
        """生成基于当前月份的可记忆激活码"""
        month = datetime.now().month
        year = datetime.now().year

        # 创建好记的激活码格式：MONTH-YEAR-WORD
        month_words = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN",
                       "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"]
        word_part = month_words[month - 1]

        # 创建数字部分使用简单算法确保好记
        num_part = f"{(year % 100) + month:04d}"  # 取年份后两位加月份，补齐4位

        # 组合成最终激活码，如 "MAY-2468-OPEN"
        activation_code = f"{word_part}-{num_part}-{self._get_season_word(month)}"
        return activation_code

    def _get_season_word(self, month):
        """根据月份返回季节相关单词，使激活码更好记"""
        if 3 <= month <= 5:
            return "SPRING"
        elif 6 <= month <= 8:
            return "SUMMER"
        elif 9 <= month <= 11:
            return "AUTUMN"
        else:
            return "WINTER"

    def encrypt_code(self, code):
        """加密激活码"""
        return self.cipher.encrypt(code.encode()).decode()

    def decrypt_code(self, encrypted_code):
        """解密激活码"""
        return self.cipher.decrypt(encrypted_code.encode()).decode()

    def save_license(self, code, filename="license.dat"):
        """保存加密后的许可证文件"""
        encrypted = self.encrypt_code(code)
        with open(filename, 'w') as f:
            f.write(encrypted)

    def load_license(self, filename="license.dat"):
        """加载并解密许可证文件"""
        try:
            with open(filename, 'r') as f:
                encrypted = f.read()
            return self.decrypt_code(encrypted)
        except:
            return None

    def show_activation_dialog(self):
        """显示Tkinter激活码输入对话框"""
        root = tk.Tk()
        root.withdraw()  # 隐藏主窗口

        # 创建输入对话框
        activation_code = simpledialog.askstring(
            title="程序激活",
            prompt="请输入激活码:",
            parent=root
        )

        return activation_code

    def show_message(self, title, message, is_error=False):
        """显示消息框"""
        root = tk.Tk()
        root.withdraw()
        if is_error:
            messagebox.showerror(title, message)
        else:
            messagebox.showinfo(title, message)

class SettingsApp:
    def __init__(self, root):
        self.root = root
        self.root.title(f"{get_app_name()}测试设置")
        self.root.geometry("800x700")  # 增加了窗口高度以容纳新设置项
        # 是否自动下单
        self.auto_order = '0'
        self.radical_app = '0'

        # 加载设置
        self.settings = self.load_settings()

        # 创建设置界面
        self.create_settings_ui()

        self.result_setting = self.load_result_settings()

    def create_settings_ui(self):
        # 使用frame组织布局
        self.main_frame = ttk.Frame(self.root, padding="20")
        self.main_frame.pack(fill=tk.BOTH, expand=True)

        # 使用网格布局管理器
        row = 0
        # 总金额设置
        ttk.Label(self.main_frame, text="总金额(元):").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.total_money_entry = ttk.Entry(self.main_frame)
        self.total_money_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.total_money_entry.insert(0, self.settings['total_money'])
        row += 1

        # 止盈金额设置
        ttk.Label(self.main_frame, text="止盈金额(元):").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.profit_money_entry = ttk.Entry(self.main_frame)
        self.profit_money_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.profit_money_entry.insert(0, self.settings['profit_money'])
        row += 1

        #押注选择号码
        ttk.Label(self.main_frame, text="押注选择号码:").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.choose_number_entry = ttk.Entry(self.main_frame)
        self.choose_number_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.choose_number_entry.insert(0, self.settings['choose_number'])
        row += 1

        # 触发次数
        ttk.Label(self.main_frame, text="参考位置").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.trigger_count_entry = ttk.Entry(self.main_frame)
        self.trigger_count_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.trigger_count_entry.insert(0, self.settings['trigger_count'])
        row += 1

        # 初始押注金额
        ttk.Label(self.main_frame, text="初始押注金额(元):").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.init_money_entry = ttk.Entry(self.main_frame)
        self.init_money_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.init_money_entry.insert(0, self.settings['init_money'])
        row += 1

        # 运行时间设置
        ttk.Label(self.main_frame, text="运行时间(小时):").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.run_time_entry = ttk.Entry(self.main_frame)
        self.run_time_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.run_time_entry.insert(0, self.settings['run_time'])
        row += 1

        # IP设置
        ttk.Label(self.main_frame, text="IP:").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.ip_entry = ttk.Entry(self.main_frame)
        self.ip_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.ip_entry.insert(0, self.settings['ip'])
        row += 1

        # Cookie 设置
        ttk.Label(self.main_frame, text="Cookie 值:").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.cookie_entry = ttk.Entry(self.main_frame)
        self.cookie_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.cookie_entry.insert(0, self.settings['cookie_value'])
        row += 1

        # 浏览器刷新时间设置
        ttk.Label(self.main_frame, text="浏览器刷新时间（单位秒）:").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.refresh_time_entry = ttk.Entry(self.main_frame)
        self.refresh_time_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.refresh_time_entry.insert(0, self.settings['refresh_time'])
        row += 1

        # Cookie 设置
        ttk.Label(self.main_frame, text="进场次数:").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.start_count_entry = ttk.Entry(self.main_frame)
        self.start_count_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.start_count_entry.insert(0, self.settings['start_count'])
        row += 1

          # Cookie 设置
        ttk.Label(self.main_frame, text="总期数:").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.total_num_entry = ttk.Entry(self.main_frame)
        self.total_num_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.total_num_entry.insert(0, self.settings['total_num'])
        row += 1

        ttk.Label(self.main_frame, text="中的总个数:").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.win_cnt_entry = ttk.Entry(self.main_frame)
        self.win_cnt_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.win_cnt_entry.insert(0, self.settings['win_cnt'])
        row += 1

        ttk.Label(self.main_frame, text="是否马上下注:").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.right_now_entry = ttk.Entry(self.main_frame)
        self.right_now_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.right_now_entry.insert(0, self.settings['right_now'])
        row += 1
        
        ttk.Label(self.main_frame, text="比对方向(<,>):").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.direct_entry = ttk.Entry(self.main_frame)
        self.direct_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.direct_entry.insert('0', self.settings['direct'])
        row += 1

        ttk.Label(self.main_frame, text="计数器（倍率）:").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.jsq_entry = ttk.Entry(self.main_frame)
        self.jsq_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.jsq_entry.insert('0', self.settings['jsq'])
        row += 1

        
        ttk.Label(self.main_frame, text="计数器止盈:").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.jsqzy_entry = ttk.Entry(self.main_frame)
        self.jsqzy_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.jsqzy_entry.insert('0', self.settings['jsqzy'])
        row += 1

        # 原始代码（仅开始时间文本框）
        ttk.Label(self.main_frame, text="采集时间范围起始点:").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.cai_start_entry = ttk.Entry(self.main_frame)
        self.cai_start_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.cai_start_entry.insert('0', self.settings['cai_start'])
        row += 1
        # 新增：结束时间文本框和分隔符
        # 分隔符（放置在column=2）
        ttk.Label(self.main_frame, text="采集时间范围终止点:").grid(row=row, column=0, sticky=tk.W, pady=5)  # padx增加左右间距
        # 结束时间文本框（放置在column=3）
        self.cai_end_entry = ttk.Entry(self.main_frame)
        self.cai_end_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.cai_end_entry.insert('0', self.settings['cai_end'])  # 假设设置中有cai_end
        row += 1
        ttk.Label(self.main_frame, text="开后压几次：").grid(row=row, column=0, sticky=tk.W, pady=5)
        self.wager_cnt_entry = ttk.Entry(self.main_frame)
        self.wager_cnt_entry.grid(row=row, column=1, sticky=tk.EW, pady=5)
        self.wager_cnt_entry.insert('0', self.settings['wager_cnt'])
        row += 1
        

        # 按钮框架
        self.button_frame = ttk.Frame(self.main_frame)
        self.button_frame.grid(row=row, column=0, columnspan=2, pady=20)


        self.per_button = ttk.Button(self.button_frame, text="重置配置", command= self.save_per_config)
        self.per_button.pack(side=tk.LEFT, padx=5)
        # 保存按钮
        self.save_button = ttk.Button(self.button_frame, text="同步总期数", command= self.show_loading_and_run)
        self.save_button.pack(side=tk.LEFT, padx=5)

        # 启动按钮
        self.start_button = ttk.Button(self.button_frame, text="启动应用", command=self.launch_app)
        self.start_button.pack(side=tk.LEFT, padx=5)

        # 配置网格权重使输入框可以扩展
        self.main_frame.columnconfigure(1, weight=1)

    
    def long_running_task(self,ip,cookie,choose_number,jsq,cai_start,cai_end):
        try:
            host = f"https://{ip}"
            flag = spiderData(cookie,11,ip,host,choose_number,jsq,cai_start,cai_end)

            
            if flag:
                # 成功时更新UI
                self.root.after(0, lambda: messagebox.showinfo("成功", "同步配置成功"))
                        
                
                # 读取配置并更新UI
                config = configparser.ConfigParser()
                config.read(CONFIG_FILE)
                
                # 清空现有内容并插入新值
                self.root.after(0, lambda: self.win_cnt_entry.delete(0, tk.END))
                self.root.after(0, lambda: self.win_cnt_entry.insert(0, config.get('SETTINGS', 'win_cnt', fallback='0')))
                
                self.root.after(0, lambda: self.total_num_entry.delete(0, tk.END))
                self.root.after(0, lambda: self.total_num_entry.insert(0, config.get('SETTINGS', 'total_num', fallback='0')))
            else:
                # 失败时显示消息
                self.root.after(0, lambda: messagebox.showinfo("失败", "同步配置失败，需要手动设置"))
        
        except Exception as e:
            error_msg = str(e)
            # 错误处理
            self.root.after(0, lambda msg=error_msg: messagebox.showerror("错误", f"同步过程中出错: {msg}"))
        
        finally:
            # 确保关闭加载框并启用按钮
            self.root.after(0, self.loading.close)

    
    def save_per_config(self):
        config2 = configparser.ConfigParser()
        config2['SETTINGS'] = {
        'ten_two': "0",
        'two_three': "0",
        'three_four':"0",
        'four_last': "0",
        'not_win_cnt':"0"
    }
        with open(per_cfg_file, 'w') as configfile:
            config2.write(configfile)
        messagebox.showinfo("提示", "重置配置成功")
        
    def show_loading_and_run(self):
        config = configparser.ConfigParser()

        # 创建配置部分
        config['SETTINGS'] = {
            'total_money': self.total_money_entry.get(),
            'init_money': self.init_money_entry.get(),
            'run_time': self.run_time_entry.get(),
            'ip': self.ip_entry.get().strip(),
            'cookie_value': self.cookie_entry.get(),
            'trigger_count': self.trigger_count_entry.get(),
            'refresh_time': self.refresh_time_entry.get(),
            'choose_number': self.choose_number_entry.get(),
            'start_count': self.start_count_entry.get(),
            'total_num': self.total_num_entry.get(),
            'win_cnt': self.win_cnt_entry.get(),
            'profit_money': self.profit_money_entry.get(),
            'right_now': self.right_now_entry.get(),
            'direct': self.direct_entry.get(),
            'jsq':self.jsq_entry.get(),
            'jsqzy':self.jsqzy_entry.get(),
            'cai_start':self.cai_start_entry.get(),
            'cai_end':self.cai_end_entry.get(),
            'wager_cnt':self.wager_cnt_entry.get()
        }

        # 写入配置文件
        with open(CONFIG_FILE, 'w') as configfile:
            config.write(configfile)
            
        ip = self.ip_entry.get().strip()
        cookie = self.cookie_entry.get().strip()
        choose_number = self.choose_number_entry.get()
        jsq = self.jsq_entry.get()
        cai_start = self.cai_start_entry.get()
        cai_end = self.cai_end_entry.get()
        self.loading = SimpleLoadingDialog(self.root, "处理中", "正在同步数据操作...")
       # 在新线程中执行耗时任务
        threading.Thread(
            target=self.long_running_task,
            args=(ip, cookie,choose_number,jsq,cai_start,cai_end),  # 传递参数
            daemon=True
        ).start()

    def save_settings(self):
        config = configparser.ConfigParser()

        # 创建配置部分
        config['SETTINGS'] = {
            'total_money': self.total_money_entry.get(),
            'init_money': self.init_money_entry.get(),
            'run_time': self.run_time_entry.get(),
            'ip': self.ip_entry.get().strip(),
            'cookie_value': self.cookie_entry.get(),
            'trigger_count': self.trigger_count_entry.get(),
            'refresh_time': self.refresh_time_entry.get(),
            'choose_number': self.choose_number_entry.get(),
            'start_count': self.start_count_entry.get(),
            'total_num': self.total_num_entry.get(),
            'win_cnt': self.win_cnt_entry.get(),
            'profit_money': self.profit_money_entry.get(),
            'right_now': self.right_now_entry.get(),
            'direct': self.direct_entry.get(),
            'jsq':self.jsq_entry.get(),
            'jsqzy':self.jsqzy_entry.get(),
            'cai_start':self.cai_start_entry.get(),
            'cai_end':self.cai_end_entry.get(),
            'wager_cnt':self.wager_cnt_entry.get()
        }

        # 写入配置文件
        with open(CONFIG_FILE, 'w') as configfile:
            config.write(configfile)

    def load_settings(self):
        # 如果配置文件不存在，使用默认值
        if not os.path.exists(CONFIG_FILE):
            return {
                'total_money': '10000',
                'profit_money': '5000',
                'init_money': '100',
                'run_time': '24',
                'ip': 'c145902.sys998.com',
                'cookie_value': '',
                'refresh_time': '180',
                'trigger_count': '1',
                'choose_number': '01:01,02:02,03:03,04:04',
                'start_count': '20',
                'total_num': '0',
                'win_cnt': '0',
                'right_now':'0',
                'direct':'<',
                'jsq':'2.5',
                'jsqzy':'',
                'cai_start':'9',
                'cai_end':'9',
                'wager_cnt':'0'
            }

        config = configparser.ConfigParser()
        config.read(CONFIG_FILE)

        # 返回配置字典，如果某个键不存在则使用默认值
        return {
            'total_money': config.get('SETTINGS', 'total_money', fallback='5000'),
            'init_money': config.get('SETTINGS', 'init_money', fallback='2'),
            'run_time': config.get('SETTINGS', 'run_time', fallback='24'),
            'ip': config.get('SETTINGS', 'ip', fallback='c145902.sys998.com'),
            'cookie_value': config.get('SETTINGS', 'cookie_value', fallback=''),
            'refresh_time': config.get('SETTINGS', 'refresh_time', fallback='180'),
            'trigger_count': config.get('SETTINGS', 'trigger_count', fallback='1'),
            'profit_money': config.get('SETTINGS', 'profit_money', fallback='5000'),
            'choose_number': config.get('SETTINGS', 'choose_number', fallback='01:01,02:02,03:03,04:04'),
            'start_count': config.get('SETTINGS', 'start_count', fallback='20'),
            'total_num': config.get('SETTINGS', 'total_num', fallback='0'),
            'win_cnt': config.get('SETTINGS', 'win_cnt', fallback='0'),
            'right_now': config.get('SETTINGS', 'right_now', fallback='0'),
            'direct': config.get('SETTINGS', 'direct', fallback='<'),
            'jsq': config.get('SETTINGS', 'jsq', fallback='2.5'),
            'jsqzy': config.get('SETTINGS', 'jsqzy', fallback=''),
            'cai_start': config.get('SETTINGS', 'cai_start', fallback='9'),
            'cai_end': config.get('SETTINGS', 'cai_end', fallback='9'),
            'wager_cnt':config.get('SETTINGS', 'wager_cnt', fallback='9')
        }

    def save_control_settings(self):
        config = configparser.ConfigParser()

        # 创建配置部分
        config['CONTROL'] = {
            'auto_order': self.auto_order,
            'radical_app': self.radical_app
        }
        # 写入配置文件
        with open(CONTROL_FILE, 'w') as configfile:
            config.write(configfile)

    def load_result_settings(self):
        # 如果配置文件不存在，使用默认值
        if not os.path.exists(RESULT_FILE):
            return {
                'total_money': '5000',
                'init_money': '2',
                'betting_number': '',
                'betting_position': '',
                'betting_cnt': '',
                'next_spider_date': '',
                'current_issue_no': '',
                'current_open_code': '',
                'stop_time': '',
                'win_cnt': '0',
                'win_money': '0',
                'betting_money': '10',
                'all_money': '',
                'all_cnt': '',
                'win_total_count':'0',
                'desc':'',
                'not_win_cnt_desc':''
            }

        config = configparser.ConfigParser()
        config.read(RESULT_FILE)

        # 返回配置字典，如果某个键不存在则使用默认值
        return {
            'total_money': config.get('RESULT', 'total_money', fallback='600'),
            'init_money': config.get('RESULT', 'init_money', fallback='10'),
            'betting_number': config.get('RESULT', 'betting_number', fallback=''),
            'betting_position': config.get('RESULT', 'betting_position', fallback=''),
            'betting_cnt': config.get('RESULT', 'betting_cnt', fallback='0'),
            'next_spider_date': config.get('RESULT', 'next_spider_date', fallback=''),
            'current_issue_no': config.get('RESULT', 'current_issue_no', fallback=''),
            'current_open_code': config.get('RESULT', 'current_open_code', fallback=''),
            'stop_time': config.get('RESULT', 'stop_time', fallback=''),
            'win_cnt': config.get('RESULT', 'win_cnt', fallback='0'),
            'win_money': config.get('RESULT', 'win_money', fallback='0'),
            'betting_money': config.get('RESULT', 'betting_money', fallback='0'),
            'all_money': config.get('RESULT', 'all_money', fallback='0'),
            'all_cnt': config.get('RESULT', 'all_cnt', fallback='0'),
            'win_total_count': config.get('RESULT', 'win_total_count', fallback='0'),
            'desc': config.get('RESULT', 'desc', fallback=''),
            'not_win_cnt_desc': config.get('RESULT', 'not_win_cnt_desc', fallback=''),
        }

    def launch_app(self):

        cookie_value = self.cookie_entry.get()
        # 判断cookie 不为空
        if cookie_value == '' or cookie_value is None:
            messagebox.showinfo("提示", "需要提供cookie_value")
            return
        # 保存当前设置
        self.save_settings()

        # 隐藏设置窗口
        self.root.withdraw()

        # 创建日志查看窗口
        self.log_window = tk.Toplevel()
        self.log_window.title(f"{get_app_name()}测试")
        self.log_window.geometry("1000x700")

        self.monitor_window = None

        self.monitor_window1 = None

        self.monitor_week_window = None

        # 设置窗口关闭时的行为
        self.log_window.protocol("WM_DELETE_WINDOW", self.on_log_window_close)

        # 创建日志界面
        self.create_log_ui()

        # 开始日志自动刷新
        self.update_log()
        # 开始结果更新
        self.update_labels()

        self.openBro = False
        self.openBro1 = False
        self.openWeekBro = False

    def create_log_ui(self):


        self.result_setting = self.load_result_settings()
        # 主框架
        main_frame = ttk.Frame(self.log_window)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # 设置信息展示框架
        settings_frame = ttk.LabelFrame(main_frame, text="当前设置", padding=5)
        settings_frame.pack(fill=tk.X, pady=(0, 5))

        # 使用网格布局展示设置信息
        settings_grid = ttk.Frame(settings_frame)
        settings_grid.pack(fill=tk.X)

        # 创建样式对象
        style = ttk.Style()

        # 定义自定义标签样式
        style.configure(
            "Colored.TLabel",  # 样式名格式: 自定义名.控件类型
            foreground="red"  # 文字颜色
        )
        ttk.Label(settings_grid, text=f"初始总金额: {self.total_money_entry.get()}元").grid(row=0, column=0,
                                                                                            sticky=tk.W,
                                                                                            padx=5, pady=2)
        ttk.Label(settings_grid, text=f"初始押注: {self.init_money_entry.get()}元").grid(row=0, column=1, sticky=tk.W,
                                                                                         padx=5, pady=2)

        ttk.Label(settings_grid, text=f"参考位置: {self.trigger_count_entry.get()}位置").grid(row=0, column=2, sticky=tk.W,
                                                                                         padx=5, pady=2)
        
        ttk.Label(settings_grid, text=f"计数器止盈数: {self.jsqzy_entry.get()}",style="Colored.TLabel").grid(row=0, column=3, sticky=tk.W,
                                                                                         padx=5, pady=2)

        # 第二列设置信息
        ttk.Label(settings_grid, text=f"运行时间: {self.run_time_entry.get()}小时").grid(row=1, column=0, sticky=tk.W,
                                                                                         padx=5, pady=2)

        self.stop_time = ttk.Label(settings_grid, text=f"执行结束时间: {self.result_setting['stop_time']}")
        self.stop_time.grid(row=1, column=1, sticky=tk.W, padx=5, pady=2)

        ttk.Label(settings_grid, text=f"每隔{int(self.refresh_time_entry.get()) / 60}分钟刷新浏览器").grid(row=1,
                                                                                                           column=2,
                                                                                                           sticky=tk.W,
                                                                                                           padx=5,
                                                                                                           pady=2)
        ttk.Label(settings_grid, text=f"地址: {self.ip_entry.get()}").grid(row=1, column=3, sticky=tk.W, padx=5, pady=2)

        # 第三列设置信息,会手动刷新的列

        self.current_issue_no = ttk.Label(settings_grid, text=f"当前期号: {self.result_setting['current_issue_no']}")
        self.current_issue_no.grid(
            row=2, column=0,
            sticky=tk.W,
            padx=5, pady=2)

        self.current_open_code = ttk.Label(settings_grid, text=f"当前号码: {self.result_setting['current_open_code']}")
        self.current_open_code.grid(
            row=2, column=1,
            sticky=tk.W,
            padx=5, pady=2)
        self.next_spider_date = ttk.Label(settings_grid,
                                          text=f"下次数据更新时间: {self.result_setting['next_spider_date']}")
        self.next_spider_date.grid(row=2,
                                   column=2,
                                   sticky=tk.W,
                                   padx=5,
                                   pady=2)
        self.total_money = ttk.Label(settings_grid, text=f"剩余可用金额: {self.result_setting['total_money']}元")
        self.total_money.grid(row=2, column=3,
                              sticky=tk.W,
                              padx=5, pady=2)

        self.betting_money = ttk.Label(settings_grid, text=f"押注金额: {self.result_setting['betting_money']}元")

        self.betting_money.grid(row=3, column=0, sticky=tk.W, padx=5, pady=2)

        self.betting_number = ttk.Label(settings_grid, text=f"押注号码: {self.result_setting['betting_number']}")
        self.betting_number.grid(row=3, column=1, sticky=tk.W, padx=5, pady=2)

        self.betting_cnt = ttk.Label(settings_grid, text=f"押注次数: {self.result_setting['betting_cnt']}")
        self.betting_cnt.grid(row=3, column=2, sticky=tk.W, padx=5, pady=2)

        self.cai_start = ttk.Label(settings_grid, text=f"采集时间: 次日{self.cai_start_entry.get()}点-今日{self.cai_end_entry.get()}",style="Colored.TLabel")
        self.cai_start.grid(row=3, column=3, sticky=tk.W, padx=5, pady=2)

        ttk.Label(settings_grid, text=f"押注选择号码: {self.choose_number_entry.get()}").grid(row=7, column=1,
                                                                                              sticky=tk.W,
                                                                                              padx=5, pady=2)

        self.win_cnt = ttk.Label(settings_grid,
                                 text=f"累计押注次数：{self.result_setting['all_cnt']},累计中奖次数:{self.result_setting['win_cnt']},累计中奖个数:{self.result_setting['win_total_count']}，累计中奖金额: {self.result_setting['win_money']}元,累计下注金额：{self.result_setting['all_money']}",
                                 style="Colored.TLabel")
        self.win_cnt.grid(
            row=7, column=0,
            sticky=tk.W,
            padx=5, pady=2)

        # 定时刷新程序
        ttk.Button(settings_grid, text="开始刷新浏览器", command=self.start_refreshing).grid(row=4, column=3,
                                                                                             sticky=tk.W,
                                                                                             padx=5, pady=2)
        tk.Button(settings_grid, text="停止刷新浏览器", command=self.stop_refreshing).grid(row=4, column=4, sticky=tk.W,
                                                                                           padx=5, pady=2)
        
        tk.Button(settings_grid, text="打开K线图", command=self.open_monitor).grid(row=4, column=0, sticky=tk.W,
                                                                                           padx=5, pady=2)
        
        tk.Button(settings_grid, text="打开任意时间K线图", command=self.open_monitor1).grid(row=4, column=1, sticky=tk.W,
                                                                                           padx=5, pady=2)

        
        tk.Button(settings_grid, text="打开周K线图", command=self.open_week_monitor).grid(row=4, column=2, sticky=tk.W,
                                                                                           padx=5, pady=2)
        
        self.desc = ttk.Label(settings_grid,
                                 text=f"{self.result_setting['desc']}",
                                 style="Colored.TLabel")
        self.desc.grid(
            row=8, column=0,
            sticky=tk.W,
            padx=5, pady=2)
        

        self.not_win_cnt_desc = ttk.Label(settings_grid,
                                 text=f"{self.result_setting['not_win_cnt_desc']}",
                                 style="Colored.TLabel")
        self.not_win_cnt_desc.grid(
            row=9, column=0,
            sticky=tk.W,
            padx=5, pady=2)
            

        tk.Button(settings_grid, text="开始自动下单", command=self.auto_save_order).grid(row=5, column=0, sticky=tk.W,
                                                                                         padx=5, pady=2)
        

        tk.Button(settings_grid, text="停止自动下单", command=self.auto_reject_order).grid(row=5, column=1, sticky=tk.W,
                                                                                           padx=5, pady=2)

        tk.Button(settings_grid, text="启动平压程序", command=self.start_analysis).grid(row=6, column=0, sticky=tk.W,
                                                                                        padx=5, pady=2)

        tk.Button(settings_grid, text="启动追击程序", command=self.open_radical_app).grid(row=6, column=1, sticky=tk.W,
                                                                                        padx=5, pady=2)

 

        # 日志显示区域
        log_frame = ttk.LabelFrame(main_frame, text="测试日志", padding=10)
        log_frame.pack(fill=tk.BOTH, expand=True)

        self.log_text = scrolledtext.ScrolledText(
            log_frame,
            wrap=tk.WORD,
            width=80,
            height=15,  # 减少了高度因为上面有设置信息区域
            font=('Consolas', 10)
        )
        self.log_text.pack(fill=tk.BOTH, expand=True)

        # 控制按钮框架
        self.control_frame = ttk.Frame(main_frame)
        self.control_frame.pack(fill=tk.X, pady=(10, 0))

        # 返回按钮
        self.back_button = ttk.Button(
            self.control_frame,
            text="返回设置",
            command=self.back_to_settings
        )
        self.back_button.pack(side=tk.LEFT)

        # 刷新按钮
        self.refresh_button = ttk.Button(
            self.control_frame,
            text="手动刷新",
            command=self.read_log_file
        )
        self.refresh_button.pack(side=tk.LEFT, padx=5)

        # 自动刷新复选框
        self.auto_refresh_var = tk.BooleanVar(value=True)
        self.auto_refresh_check = ttk.Checkbutton(
            self.control_frame,
            text="自动刷新",
            variable=self.auto_refresh_var
        )
        self.auto_refresh_check.pack(side=tk.LEFT, padx=5)

        # 清空日志按钮
        self.clear_button = ttk.Button(
            self.control_frame,
            text="清空日志",
            command=self.clear_log_file
        )
        self.clear_button.pack(side=tk.RIGHT)

        # 初始读取日志
        self.read_log_file()

    def read_log_file(self):
        try:
            if os.path.exists(LOG_FILE):
                with open(LOG_FILE, 'r', encoding='utf-8') as f:
                    content = f.read()
                self.log_text.delete(1.0, tk.END)
                self.log_text.insert(tk.END, content)
                self.log_text.see(tk.END)  # 滚动到底部
            else:
                self.log_text.delete(1.0, tk.END)
                self.log_text.insert(tk.END, "日志文件不存在，将自动创建。\n")
        except Exception as e:
            self.log_text.insert(tk.END, f"读取日志文件出错: {str(e)}\n")

    def update_log(self):
        if hasattr(self, 'log_window') and self.log_window.winfo_exists():
            if self.auto_refresh_var.get():
                self.read_log_file()
            self.log_window.after(2000, self.update_log)  # 每2秒刷新一次

    def update_labels(self):
        """更新所有标签的文本内容"""
        try:
            self.result_setting = self.load_result_settings()
            # 更新每个标签的文本
            self.current_issue_no.config(text=f"当前期号: {self.result_setting['current_issue_no']}")
            self.current_open_code.config(text=f"当前号码: {self.result_setting['current_open_code']}")
            self.next_spider_date.config(text=f"下次数据时间: {self.result_setting['next_spider_date']}")
            self.total_money.config(text=f"剩余金额: {self.result_setting['total_money']}元")
            self.betting_money.config(text=f"押注金额: {self.result_setting['betting_money']}元")
            self.betting_number.config(text=f"押注号码: {self.result_setting['betting_number']}")
            self.betting_cnt.config(text=f"押注次数: {self.result_setting['betting_cnt']}")
            self.stop_time.config(text=f"执行结束时间: {self.result_setting['stop_time']}")
            self.win_cnt.config(
                text=f"累计押注次数：{self.result_setting['all_cnt']},累计中奖次数:{self.result_setting['win_cnt']},累计中奖个数:{self.result_setting['win_total_count']}，累计中奖金额: {self.result_setting['win_money']}元,累计下注金额：{self.result_setting['all_money']}")
            self.desc.config(text=f"{self.result_setting['desc']}")

            self.not_win_cnt_desc.config(text=f"{self.result_setting['not_win_cnt_desc']}")

            current_date_1 = datetime.now().strftime('%Y%m%d')
            save_dir = f"spider_char_data_{current_date_1}"
            save_dir1 = f"spider_char_data_week_{current_date_1}"
            save_dir2 = f"spider_char_car_data_{current_date_1}"
            html_file = f"{os.getcwd()}\\{save_dir}\\lottery_reports\\car\\lottery_analysis_{datetime.now().strftime('%Y-%m-%d')}.html"
            
            html_file2= f"{os.getcwd()}\\{save_dir2}\\lottery_reports\\car4\\lottery_analysis_{datetime.now().strftime('%Y-%m-%d')}.html"
            if  os.path.exists(html_file) and self.monitor_window is None:
                open_with_browser(html_file)
                self.monitor_window = "1"
            html_file1 = f"{os.getcwd()}\\{save_dir1}\\lottery_reports\\car\\summary.html"
            if  os.path.exists(html_file1) and self.monitor_week_window is None:
                open_with_browser(html_file1)
                self.monitor_week_window = "1"

            if  os.path.exists(html_file2) and self.monitor_window1 is None:
                open_with_browser(html_file2)
                self.monitor_window1 = "1"
        except Exception as e:
            logger.error(f"更新标签时出错: {e}")
        # 2秒后再次调用自身（实现定时更新）
        self.root.after(2000, self.update_labels)

    def clear_log_file(self):
        try:
            with open(LOG_FILE, 'w', encoding='utf-8') as f:
                f.write(f"日志已清空于 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
            self.read_log_file()
        except Exception as e:
            messagebox.showerror("错误", f"清空日志文件失败: {str(e)}")

    def back_to_settings(self):
        # 关闭日志窗口
        self.log_window.destroy()
        # 重新显示设置窗口
        self.root.deiconify()

    def on_log_window_close(self):
        # 关闭日志窗口时返回到设置界面
        self.back_to_settings()

    def refresh_chrome(self):
        try:
            while True:
                if start_refresh:
                    # 激活Chrome窗口（假设Chrome已经是打开的）
                    pyautogui.hotkey('alt', 'tab')  # 切换到Chrome窗口
                    time.sleep(1)  # 等待1秒确保窗口切换完成

                    # 发送F5刷新
                    pyautogui.press('f5')
                    logger.info(f"已刷新页面 - {time.strftime('%Y-%m-%d %H:%M:%S')}")

                    # 等待3分钟（180秒）
                    time.sleep(int(self.refresh_time_entry.get()))
        except KeyboardInterrupt:
            logger.error("脚本已停止")

    def start_refreshing(self):
        global start_refresh
        start_refresh = True
        threading.Thread(target=self.refresh_chrome, daemon=True).start()
        messagebox.showinfo("提示", "自动刷新已启动！")

    def open_monitor(self):

        if self.openBro == True:
            messagebox.showinfo("提示", "K线图数程序已经启动,不需要重新触发，等会自动打开浏览器窗口")
            return
        self.settings = self.load_settings()
        messagebox.showinfo("提示", "K线图数程序已经启动,等会自动打开浏览器窗口")
        cookie_value = self.settings['cookie_value']
        ip = self.settings['ip']
        host = f"https://{self.settings['ip']}"
        choose_number = self.settings['choose_number']
        jsq = self.settings['jsq']
        initial_capital = self.settings['total_money']
        stop_capital_threshold = self.settings['profit_money']
        base_bet_amount = self.settings['init_money']

        threading.Thread(target=spiderCharData, kwargs={'cookie_value': cookie_value, 'lottery_id': lottery_id_data(),
                                                            'ip': ip,'host':host,'choose_number':choose_number,'jsq':jsq,'initial_capital':initial_capital,'base_bet_amount':base_bet_amount,'stop_capital_threshold':stop_capital_threshold}, daemon=True).start()
        self.openBro = True
    def open_monitor1(self):

        if self.openBro1 == True:
            messagebox.showinfo("提示", "任意时间K线图数程序已经启动,不需要重新触发，等会自动打开浏览器窗口")
            return
        self.settings = self.load_settings()
        messagebox.showinfo("提示", "任意时间K线图数程序已经启动,等会自动打开浏览器窗口")
        cookie_value = self.settings['cookie_value']
        ip = self.settings['ip']
        host = f"https://{self.settings['ip']}"
        choose_number = self.settings['choose_number']
        jsq = self.settings['jsq']
        initial_capital = self.settings['total_money']
        stop_capital_threshold = self.settings['profit_money']
        base_bet_amount = self.settings['init_money']
        cai_start = self.settings['cai_start']
        cai_end = self.settings['cai_end']

        threading.Thread(target=spiderCharData1, kwargs={'cookie_value': cookie_value, 'lottery_id': lottery_id_data(),
                                                            'ip': ip,'host':host,'choose_number':choose_number,'jsq':jsq,'initial_capital':initial_capital,'base_bet_amount':base_bet_amount,'stop_capital_threshold':'10000','cai_start':cai_start,'cai_end':cai_end}, daemon=True).start()
        self.openBro1 = True
    
    def open_week_monitor(self):

        if self.openWeekBro == True:
            messagebox.showinfo("提示", "周K线图数程序已经启动,不需要重新触发，预计10分钟自动打开浏览器窗口")
            return
        self.settings = self.load_settings()
        messagebox.showinfo("提示", "周K线图数程序已经启动,预计10分钟自动打开浏览器窗口")
        cookie_value = self.settings['cookie_value']
        ip = self.settings['ip']
        host = f"https://{self.settings['ip']}"
        choose_number = self.settings['choose_number']
        jsq = self.settings['jsq']

        threading.Thread(target=spiderWeekCharData, kwargs={'cookie_value': cookie_value, 'lottery_id': lottery_id_data(),
                                                            'ip': ip,'host':host,'choose_number':choose_number,'jsq':jsq}, daemon=True).start()
        self.openWeekBro = True

    def stop_refreshing(self):
        # 由于是通过KeyboardInterrupt停止，这里只是提示
        global start_refresh
        messagebox.showinfo("提示", "自动刷新已停止")
        start_refresh = False

    def start_analysis(self):
        response = messagebox.askyesno("确认", "确定要执行此操作吗？")
        self.radical_app = '0'
        # 保存自动下单
        self.save_control_settings()
        if response:
            threading.Thread(target=start_analysis, kwargs={'config_file': CONFIG_FILE, 'result_file': RESULT_FILE,
                                                            'control_file': CONTROL_FILE}, daemon=True).start()

    def auto_save_order(self):
        self.auto_order = '1'
        # 保存自动下单
        self.save_control_settings()
        messagebox.showinfo("提示", "已经开启自动下单")

    def auto_reject_order(self):
        self.auto_order = '0'
        # 保存自动下单
        self.save_control_settings()
        messagebox.showinfo("提示", "已经停止自动下单")

    def open_radical_app(self):
        self.radical_app = '1'
        # 保存自动下单
        self.save_control_settings()
        response = messagebox.askyesno("确认", "确定要执行启动追击程序吗？")
        if response:
            threading.Thread(target=start_analysis, kwargs={'config_file': CONFIG_FILE, 'result_file': RESULT_FILE,
                                                            'control_file': CONTROL_FILE}, daemon=True).start()
        messagebox.showinfo("提示", f"已经启动激进的押注")

    def now_radical_app(self):
        self.radical_app = '2'
        # 保存自动下单
        self.save_control_settings()
        response = messagebox.askyesno("确认", "确定要执行直接押注程序吗？")
        if response:
            threading.Thread(target=start_analysis, kwargs={'config_file': CONFIG_FILE, 'result_file': RESULT_FILE,
                                                            'control_file': CONTROL_FILE}, daemon=True).start()


def main():
    system = ActivationSystem()
    # 1. 检查是否已激活
    loaded_code = system.load_license()
    current_code = system.generate_memorable_code()
    # print(f"[开发者信息] 本月正确激活码: {current_code}")  # 仅用于演示
    client = DeviceManagerClient("http://106.54.59.176")
    try:
        result = client.check_mac()  # 不传参数则自动获取本机MAC
    except:
        print('异常了')
    if result.get("status")== 'stop':
        exit()
    if loaded_code == current_code:
        # system.show_message("激活状态", "程序已激活！")
        root = tk.Tk()
        app = SettingsApp(root)
        root.mainloop()
    elif result.get("status")== 'success':
        root = tk.Tk()
        app = SettingsApp(root)
        root.mainloop()
    else:
        # 2. 未激活则要求输入激活码
        system.show_message("激活提示", "程序需要激活才能使用", is_error=False)

        # 3. 生成本月正确激活码（实际应用中不应该显示给用户）
        current_code = system.generate_memorable_code()
        print(f"[开发者信息] 本月正确激活码: {current_code}")  # 仅用于演示

        # 4. 获取用户输入
        user_input = system.show_activation_dialog()

        if user_input is None:  # 用户点击了取消
            system.show_message("激活取消", "您取消了激活，程序将退出", is_error=True)
            exit()

        # 5. 验证激活码
        if user_input == current_code:
            system.save_license(current_code)
            system.show_message("激活成功", "程序已成功激活！")
            # 这里可以继续执行主程序
            root = tk.Tk()
            app = SettingsApp(root)
            root.mainloop()
        else:
            system.show_message("激活失败", "激活码不正确！", is_error=True)
            exit()


if __name__ == "__main__":
    global logger

    logger = setup_logging(
        name="app",
        log_dir="./runtime/logs",
        level="DEBUG"
    )

    log_path = Path(LOG_FILE)
    # 创建父目录（如果不存在）
    log_path.parent.mkdir(parents=True, exist_ok=True)
    # 创建文件（如果不存在）
    log_path.touch(exist_ok=True)

    main()
